<!DOCTYPE html>

<html>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传</title>

    <style type="text/css">
        .file-uploader {
            display: block;
            width: 400px;
            border: 1px solid gray;
            margin: auto;
        }
        
        .file-uploader input[name=upfile] {
            display: none!important;
            opacity: 0.01;
        }
        
        .file-uploader .file-selector {
            overflow: auto;
            border: 1px solid blue;
            margin: 5px;
        }
        
        .file-uploader .file-name {
            float: left;
            width: 80%;
            height: 50px;
            line-height: 50px;
        }
        
        .file-uploader .btn-select {
            float: right;
            width: 20%;
            height: 50px;
            line-height: 50px;
            text-align: center;
            background: #9696fa;
            color: #fff;
        }
        
        .file-uploader .btn-select:hover {
            background: blue;
        }
        
        .file-uploader .image-preview {
            height: 200px;
            border: 1px solid green;
            margin: 5px;
            overflow: hidden;
        }
        
        .file-uploader .image-preview>img {
            height: 100%;
            vertical-align: middle;
        }
    </style>
</head>

<body>

    <!-- 如果需要使用 表单来上传文件，则必 method 属性值必须为 post  -->
    <!-- 同时 enctype 属性值必须为 multipart/form-data -->
    <form action="" method="post" enctype="multipart/form-data">
        <!-- 暂不考虑后端相关内容，仅只做文件上传界面 -->
        <div class="file-uploader">
            <input type="file" name="upfile">
            <div class="file-selector">
                <span class="file-name"></span>
                <span class="btn-select">选择图像</span>
            </div>
            <div class="image-preview"></div>
        </div>

    </form>

    <script type="text/javascript">
        (() => {

            let preview = document.querySelector('.image-preview');

            let read = function(file) {
                // https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
                // i>、创建一个可以读取 File实例 中内容的 FileReader 实例
                let reader = new FileReader();

                let fn = function() {
                    console.log('文件内容读取结束', reader.readyState);
                    // result 所返回的数据的格式取决于使用哪个函数来启动读取操作
                    let data = reader.result; // result 表示文件的内容（该属性仅在读取操作完成后才有效）
                    console.log(data);

                    let image = preview.querySelector('img'); // 先在 preview 内部获取 img
                    if (!image) {
                        image = document.createElement('img'); // 创建 img 元素
                        preview.appendChild(image); // 将 img 元素添加到 preview 元素内
                    }

                    image.setAttribute('src', data); // image.src = data ;
                }

                // ii>、为 FileReader实例 绑定 load 事件的监听器
                reader.addEventListener('load', fn, false);

                // iii>、使用 reader 实例的 readAsDataURL 函数读取 file 中的内容
                reader.readAsDataURL(file); // 读取到 "" 格式
            }

            let change = function(event) {
                event.preventDefault(); // 阻止事件默认行为
                event.stopPropagation(); // 阻止事件传播

                let target = event.target; // 文件组件: <input type="file">
                console.dir(target); //输出target中的所有属性和值

                // 通过 <input type="file"> 元素的 files 属性来获取 FileList
                let fileList = target.files; // 获得所有 File实例 组成的 FileList集合
                let file = fileList.item(0); // let file = fileList[0] ;
                console.log(file.name, file.size, file.type);

                let fileSelector = target.nextElementSibling; // <div class="file-selector">
                let first = fileSelector.firstElementChild; // <span class="file-name">
                first.innerHTML = file.name; // 将单个文件名设置到指定区域中

                // 调用自定义的函数来读取文件内容
                read(file);
            }

            let select = function(event) {
                event.preventDefault(); // 阻止事件默认行为
                event.stopPropagation(); // 阻止事件传播

                let target = event.target;
                let parent = target.parentElement;
                let previous = parent.previousElementSibling; // 文件组件: <input type="file">
                // console.log( target , parent , first , previous );
                previous.click(); // 调用 文件组件 的 click 函数可以让浏览器弹出文件选择窗口
                previous.addEventListener('change', change, false);
            }

            let fs = document.querySelector('.file-selector');
            fs.addEventListener('click', select, false);
        })();
    </script>

    <!-- <hr>

    <div>
        <script>
            let change = function(element) {
                console.log(element.value);
            }
        </script>
        <input type="text" onchange="change(this)">
    </div> -->

</body>

</html>